package com.sky.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sky.context.BaseContext;
import com.sky.dto.OrdersPageQueryDTO;
import com.sky.dto.OrdersPaymentDTO;
import com.sky.dto.OrdersSubmitDTO;
import com.sky.entity.*;
import com.sky.exception.AddressBookBusinessException;
import com.sky.exception.ShoppingCartBusinessException;
import com.sky.mapper.AddressBookMapper;
import com.sky.mapper.OrderMapper;
import com.sky.mapper.ShopCartMapper;
import com.sky.result.PageResult;
import com.sky.service.OrderService;
import com.sky.vo.OrderPaymentVO;
import com.sky.vo.OrderSubmitVO;
import com.sky.vo.OrderVO;
import com.sky.websocket.WebSocketServer;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class OrderServiceImpl implements OrderService {
    @Autowired
    AddressBookMapper addressBookMapper;
    @Autowired
    ShopCartMapper shopCartMapper;
    @Autowired
    OrderMapper orderMapper;
    @Autowired
    WebSocketServer webSocketServer;
    @Override
    @Transactional
    public OrderSubmitVO submit(OrdersSubmitDTO ordersSubmitDTO) {
        AddressBook addressBook = addressBookMapper.getById(ordersSubmitDTO.getAddressBookId());
        LocalDateTime orderTime=LocalDateTime.now();
        String orderNumber=System.currentTimeMillis()+"";
        Orders orders=new Orders();
        List<OrderDetail> orderDetail=new ArrayList<>();
        BigDecimal amount = new BigDecimal("0");
        List<ShoppingCart> shoppingCarts = shopCartMapper.list(ShoppingCart.builder().userId(BaseContext.getCurrentId()).build());
        if(shoppingCarts==null || shoppingCarts.size()<1)throw new ShoppingCartBusinessException("购物车为空！");
        if(addressBook==null)throw new AddressBookBusinessException("地址为空！");

        for (ShoppingCart shoppingCart : shoppingCarts) {
            amount=amount.add(shoppingCart.getAmount().multiply(new BigDecimal(shoppingCart.getNumber().toString())));
            amount=amount.add(new BigDecimal(shoppingCart.getNumber().toString()));//打包费等于商品数量
        }
        orders.setAmount(amount);
        BeanUtils.copyProperties(ordersSubmitDTO,orders);
        orders.setNumber(orderNumber);
        orders.setStatus(1);
        orders.setUserId(BaseContext.getCurrentId());
        orders.setOrderTime(orderTime);
        orders.setPayStatus(0);
        orders.setAddress(addressBook.getProvinceName()+" "+addressBook.getCityName()+" "+addressBook.getDistrictName()+" "+addressBook.getDetail());
        orders.setConsignee(addressBook.getConsignee());
        orders.setPhone(addressBook.getPhone());

        orderMapper.save(orders);

        for (ShoppingCart shoppingCart : shoppingCarts) {
            OrderDetail orderDetail1=OrderDetail.builder()
                    .dishId(shoppingCart.getDishId())
                    .setmealId(shoppingCart.getSetmealId())
                    .dishFlavor(shoppingCart.getDishFlavor())
                    .image(shoppingCart.getImage())
                    .number(shoppingCart.getNumber())
                    .name(shoppingCart.getName())
                    .amount(shoppingCart.getAmount())
                    .orderId(orders.getId())
                    .build();
            orderDetail.add(orderDetail1);
        }
        orderMapper.saveDetail(orderDetail);

        shopCartMapper.clean(BaseContext.getCurrentId());

        return OrderSubmitVO.builder()
                .id(orders.getId())
                .orderNumber(orderNumber)
                .orderAmount(amount)
                .orderTime(orderTime)
                .build();
    }

    @Override
    public OrderPaymentVO pay(OrdersPaymentDTO ordersPaymentDTO) {
        //请求微信后端预支付接口，返回支付加密签，返回给前端小程序，小程序调用微信支付，支付成功后微信后台通知后端
        //Orders orders=orderMapper.queryByNumber(ordersPaymentDTO.getOrderNumber());
        //模拟
        return OrderPaymentVO.builder()
                .signType("RSA")
                .timeStamp(System.currentTimeMillis()+"")
                .packageStr("")
                .nonceStr("")
                .paySign("")
                .build();
    }
    @Override
    public void cancel(Long id) {
        Orders orders=Orders.builder().id(id).status(6).build();
        orderMapper.update(orders);
    }

    @Override
    public PageResult historyOrder(OrdersPageQueryDTO ordersPageQueryDTO) {
        PageHelper.startPage(ordersPageQueryDTO.getPage(),ordersPageQueryDTO.getPageSize());
        ordersPageQueryDTO.setUserId(BaseContext.getCurrentId());
        Page<OrderVO> page= orderMapper.pageQuery(ordersPageQueryDTO);
        page.forEach((item)->{
            List<OrderDetail> orderDetails = orderMapper.queryDetailByOrderId(item.getId());
            item.setOrderDetailList(orderDetails);
        });
        return new PageResult(page.getTotal(),page.getResult());
    }

    @Override
    public void reminder(Long id) {
        OrderVO orderVO = orderMapper.queryById(id);
        if(orderVO!=null){
            Map<String,Object> msg=new HashMap<>();
            msg.put("type",2);
            msg.put("orderId",id);
            msg.put("content","订单号:"+orderVO.getNumber());
            String s = JSON.toJSON(msg).toString();
            webSocketServer.sendToAllClient(s);
        }


    }

    @Override
    public void paySuccess(Long ordersId) {
        Orders orders=Orders.builder().id(ordersId).status(2).payStatus(1).build();
        orderMapper.update(orders);
        Map<String,Object> msg=new HashMap<>();
        msg.put("type",1);
        msg.put("orderId",ordersId);
        msg.put("content","订单号:"+ordersId);
        String s = JSON.toJSON(msg).toString();
        webSocketServer.sendToAllClient(s);
    }

    @Override
    public void payError(Long ordersId) {

    }

    @Override
    public OrderVO orderDetail(Long id) {
        OrderVO orderVO=orderMapper.queryById(id);
        List<OrderDetail> orderDetails=orderMapper.queryDetailByOrderId(id);
        orderVO.setOrderDetailList(orderDetails);
        return orderVO;
    }
}
